// Package button_service_v1
// @Author zhongxc
// @Date 2024/7/26 15:00:00
// @Desc
package button_service_v1

import (
	"context"
	"fmt"
	"github.com/jinzhu/copier"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"
	"strings"
	"time"
	"vben-admin/pkg/dao"
	"vben-admin/pkg/model"
	"vben-admin/pkg/repository"
	"vben-admin/pkg/svc"
	buttonServiceV1 "vben-grpc-common/vben-admin/types/button.service.v1"
)

type ButtonService struct {
	svcCtx *svc.ServiceContext
	buttonServiceV1.UnimplementedButtonServiceServer
	buttonDao repository.ButtonRepo
}

func NewButtonService(svcCtx *svc.ServiceContext) *ButtonService {
	return &ButtonService{
		svcCtx:    svcCtx,
		buttonDao: dao.NewButtonDao(svcCtx.Db),
	}
}

// CreateButton
// @Description: 创建按钮
// @receiver i
// @param ctx
// @param in
// @return *emptypb.Empty
// @return error
func (i *ButtonService) CreateButton(ctx context.Context, in *buttonServiceV1.CreateButtonRequest) (*emptypb.Empty, error) {
	// 参数检查
	if strings.TrimSpace(in.Name) == "" {
		return nil, status.Error(codes.InvalidArgument, "按钮名称不能为空")
	}
	if strings.TrimSpace(in.Code) == "" {
		return nil, status.Error(codes.InvalidArgument, "按钮编码不能为空")
	}

	// 按钮名称、地址重复检测
	inter, err := i.buttonDao.FindByNameOrUrl(ctx, in.Name, "")
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil {
		return nil, status.Error(codes.AlreadyExists, "按钮名称已存在")
	}
	inter, err = i.buttonDao.FindByNameOrUrl(ctx, "", in.Code)
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil {
		return nil, status.Error(codes.AlreadyExists, "按钮地址已存在")
	}

	// 组装参数
	var buttonModel model.ButtonModel
	_ = copier.Copy(&buttonModel, in)
	buttonModel.CreatedAt.Time = time.Now()
	buttonModel.CreatedAt.Valid = true

	// 保存数据
	err = i.buttonDao.CreateButton(ctx, &buttonModel)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("按钮创建失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	return &emptypb.Empty{}, nil
}

// UpdateButton
// @Description: 按钮更新
// @receiver i
// @param ctx
// @param in
// @return *emptypb.Empty
// @return error
func (i *ButtonService) UpdateButton(ctx context.Context, in *buttonServiceV1.UpdateButtonRequest) (*emptypb.Empty, error) {
	// 参数检查
	if in.Id <= 0 {
		return nil, status.Error(codes.InvalidArgument, "ID不能为空")
	}
	if strings.TrimSpace(in.Name) == "" {
		return nil, status.Error(codes.InvalidArgument, "按钮名称不能为空")
	}
	if strings.TrimSpace(in.Code) == "" {
		return nil, status.Error(codes.InvalidArgument, "按钮地址不能为空")
	}

	// 按钮名称、地址重复检测
	inter, err := i.buttonDao.FindByNameOrUrl(ctx, in.Name, "")
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil && inter.Id != in.Id {
		return nil, status.Error(codes.AlreadyExists, "按钮名称已存在")
	}
	inter, err = i.buttonDao.FindByNameOrUrl(ctx, "", in.Code)
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil && inter.Id != in.Id {
		return nil, status.Error(codes.AlreadyExists, "按钮地址已存在")
	}

	// 参数组装
	data := make(map[string]interface{})
	data["name"] = in.Name
	data["code"] = in.Code
	data["description"] = in.Description
	data["updated_by"] = in.UpdatedBy
	data["updated_at"] = time.Now()

	// 保存数据
	err = i.buttonDao.UpdateButton(ctx, in.Id, data)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("按钮更新失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}
	return &emptypb.Empty{}, nil
}

// DeleteButton
// @Description: 按钮删除
// @receiver i
// @param ctx
// @param in
// @return *emptypb.Empty
// @return error
func (i *ButtonService) DeleteButton(ctx context.Context, in *buttonServiceV1.DeleteButtonRequest) (*emptypb.Empty, error) {
	// 参数检查
	if len(in.Ids) == 0 {
		return nil, status.Error(codes.InvalidArgument, "ID不能为空")
	}

	// 数据删除
	err := i.buttonDao.DeleteButton(ctx, in.Ids)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("按钮删除失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	return &emptypb.Empty{}, nil
}

// GetButtonList
// @Description: 按钮列表
// @receiver i
// @param ctx
// @param in
// @return *buttonServiceV1.ButtonListResponse
// @return error
func (i *ButtonService) GetButtonList(ctx context.Context, in *buttonServiceV1.GetButtonListRequest) (*buttonServiceV1.ButtonListResponse, error) {
	// 参数检查
	if in.Page == 0 {
		in.Page = 1
	}
	if in.Page > 100 {
		in.Page = 100
	}
	if in.PageSize == 0 {
		in.PageSize = 10
	}
	if in.PageSize > 100 {
		in.PageSize = 100
	}

	// 数据查询
	list, err := i.buttonDao.GetButtonList(ctx, in.Name, in.Code, in.Page, in.PageSize)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("按钮列表获取失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	// 列表数据转换
	var buttonList []*buttonServiceV1.ButtonData
	for _, item := range list["data"].([]*model.ButtonModel) {
		var buttonData buttonServiceV1.ButtonData
		if item.UpdatedAt.Valid && !item.UpdatedAt.Time.IsZero() {
			buttonData.UpdatedAt = item.UpdatedAt.Time.Format(time.DateTime)
		}
		if item.CreatedAt.Valid && !item.CreatedAt.Time.IsZero() {
			buttonData.CreatedAt = item.CreatedAt.Time.Format(time.DateTime)
		}
		_ = copier.Copy(&buttonData, item)
		buttonList = append(buttonList, &buttonData)
	}

	// 数据响应
	return &buttonServiceV1.ButtonListResponse{
		TotalCount: list["totalCount"].(int64),
		Page:       list["page"].(int64),
		TotalPage:  list["totalPage"].(int64),
		Limit:      list["pageSize"].(int64),
		Data:       buttonList,
	}, nil
}

// GetButtonInfo
// @Description: 按钮详情获取
// @receiver i
// @param ctx
// @param in
// @return *buttonServiceV1.ButtonResponse
// @return error
func (i *ButtonService) GetButtonInfo(ctx context.Context, in *buttonServiceV1.GetButtonInfoRequest) (*buttonServiceV1.ButtonResponse, error) {
	// 参数检查
	if in.Id <= 0 {
		return nil, status.Error(codes.InvalidArgument, "ID不能为空")
	}

	info, err := i.buttonDao.GetButtonInfo(ctx, in.Id)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("按钮详情获取失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	if info == nil {
		return nil, status.Error(codes.NotFound, "数据不存在")
	}

	var buttonResp buttonServiceV1.ButtonResponse
	_ = copier.Copy(&buttonResp, info)

	return &buttonResp, nil
}

func (i *ButtonService) GetAll(ctx context.Context, in *emptypb.Empty) (*buttonServiceV1.ButtonAllListResponse, error) {

	list, err := i.buttonDao.GetAll(ctx)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("按钮列表获取失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, "按钮列表获取失败")
	}

	var buttonList = make([]*buttonServiceV1.ButtonData, 0)
	for _, item := range list {
		var buttonData buttonServiceV1.ButtonData
		_ = copier.Copy(&buttonData, item)
		if item.CreatedAt.Valid && !item.CreatedAt.Time.IsZero() {
			buttonData.CreatedAt = item.CreatedAt.Time.Format(time.DateTime)
		}
		if item.UpdatedAt.Valid && !item.CreatedAt.Time.IsZero() {
			buttonData.UpdatedAt = item.UpdatedAt.Time.Format(time.DateTime)
		}
		buttonList = append(buttonList, &buttonData)
	}

	return &buttonServiceV1.ButtonAllListResponse{
		Data: buttonList,
	}, nil
}
